package org.Yiran.timetale_re.datagen;

import net.minecraft.data.PackOutput;
import net.minecraft.data.recipes.FinishedRecipe;
import net.minecraft.data.recipes.RecipeProvider;
import org.Yiran.timetale_re.item.MaterialRegister;
import org.Yiran.timetale_re.Timetale_re;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.function.Consumer;

/**
 * 模组配方提供器类
 * <p>
 * 该类负责为模组生成所有物品的配方数据，包括：
 * 1. 材料相关的合成配方（粒、锭、块之间的转换）
 * 2. 材料的烧制配方（粗矿到锭、粉到锭）
 * 3. 自动生成配方JSON文件（可选功能）
 * </p>
 */
public class ModRecipeProvider extends RecipeProvider {
    
    // ============================== 实例变量 ==============================
    
    private final PackOutput output;

    // ============================== 构造方法 ==============================
    
    /**
     * 构造一个新的模组配方提供器
     * 
     * @param output 数据包输出位置
     */
    public ModRecipeProvider(PackOutput output) {
        super(output);
        this.output = output;
    }

    // ============================== 配方构建方法 ==============================
    
    /**
     * 构建所有配方
     * <p>
     * 此方法是配方生成的入口点，负责调用各种配方生成方法：
     * 1. 注册所有材料的基础合成配方
     * 2. 注册所有材料的烧制配方
     * 3. 根据系统属性决定是否生成配方JSON文件
     * </p>
     * 
     * @param consumer 配方消费者，用于接收生成的配方
     */
    @Override
    protected void buildRecipes(@NotNull Consumer<FinishedRecipe> consumer) {
        System.out.println("开始注册材料配方...");
        int materialCount = MaterialRegister.getRegisteredMaterials().size();
        System.out.println("共有 " + materialCount + " 种材料需要注册配方");

        // 注册所有材料配方
        System.out.println("开始注册基础合成配方...");
        MaterialRecipeProvider.registerAllMaterialRecipes(consumer);
        System.out.println("基础合成配方注册完成");

        // 注册所有材料的烧制配方
        System.out.println("开始注册烧制配方...");
        MaterialRecipeProvider.registerAllSmeltingRecipes(consumer);
        System.out.println("烧制配方注册完成");

        // 只有在特定条件下才自动生成配方JSON文件
        // 比如检查系统属性或者环境变量
        if (Boolean.getBoolean("timetale.generateRecipes")) {
            generateRecipeJsonFiles();
        }

        System.out.println("材料配方注册完成");
    }

    // ============================== JSON文件生成方法 ==============================
    
    /**
     * 自动生成配方JSON文件
     * <p>
     * 此方法会为所有已注册的材料生成配方JSON文件，并保存到指定目录中。
     * 仅在系统属性"timetale.generateRecipes"为true时才会执行。
     * </p>
     */
    private void generateRecipeJsonFiles() {
        System.out.println("开始生成配方JSON文件...");
        int materialCount = MaterialRegister.getRegisteredMaterials().size();
        System.out.println("共有 " + materialCount + " 种材料需要生成配方JSON文件");

        File recipeDir = new File(output.getOutputFolder().toFile(), "data/" + Timetale_re.MODID + "/recipes");
        System.out.println("配方目录路径: " + recipeDir.getAbsolutePath());
        System.out.println("配方目录是否存在: " + recipeDir.exists());

        // 列出目录中已有的文件
        if (recipeDir.exists()) {
            File[] existingFiles = recipeDir.listFiles();
            if (existingFiles != null) {
                System.out.println("现有文件数量: " + existingFiles.length);
                for (File file : existingFiles) {
                    System.out.println("现有文件: " + file.getName());
                }
            }
        } else {
            System.out.println("创建配方目录: " + recipeDir.mkdirs());
        }

        // 为每个材料生成配方JSON文件
        int generatedCount = 0;
        for (MaterialRegister.MaterialDefinition material : MaterialRegister.getRegisteredMaterials()) {
            System.out.println("正在为材料 \"" + material.getName() + "\" 生成配方JSON文件...");
            int count = generateMaterialRecipeFiles(material, recipeDir);
            generatedCount += count;
            System.out.println("材料 \"" + material.getName() + "\" 生成了 " + count + " 个配方文件");
        }

        System.out.println("配方JSON文件生成完成! 总共生成了 " + generatedCount + " 个配方文件");
    }

    /**
     * 为特定材料生成配方JSON文件
     * <p>
     * 为指定材料生成配方JSON文件，包括：
     * 1. 粒合成锭
     * 2. 锭合成块
     * 3. 块分解成锭
     * 4. 锭分解成粒
     * </p>
     * 
     * @param material 材料定义对象
     * @param recipeDir 配方文件保存目录
     * @return 生成的配方文件数量
     */
    private int generateMaterialRecipeFiles(MaterialRegister.MaterialDefinition material, File recipeDir) {
        // 获取材料的配方JSON内容
        java.util.List<String> recipeJsons = MaterialRecipeProvider.generateMaterialRecipeJsons(material);
        int generatedCount = 0;

        // 定义配方文件名
        String[] recipeNames = {
                material.getName() + "_ingot_from_nuggets.json",
                material.getName() + "_block_from_ingots.json",
                material.getName() + "_ingot_from_block.json",
                material.getName() + "_nugget_from_ingot.json"
        };

        // 写入配方文件 - 只有当文件不存在时才写入
        for (int i = 0; i < recipeJsons.size() && i < recipeNames.length; i++) {
            File recipeFile = new File(recipeDir, recipeNames[i]);
            // 如果文件已存在，跳过生成
            if (recipeFile.exists()) {
                System.out.println("配方文件已存在，跳过: " + recipeNames[i]);
                continue;
            }

            try (FileWriter writer = new FileWriter(recipeFile)) {
                writer.write(recipeJsons.get(i));
                System.out.println("已写入配方文件: " + recipeNames[i]);
                generatedCount++;
            } catch (IOException e) {
                System.err.println("写入配方文件失败: " + recipeNames[i]);
            }
        }
        
        return generatedCount;
    }
}